package com.song.user.filters;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Set;

/**
 * Zuul过滤器 （核心）
 * 类型包括：pre, route, post, error
 * 登录认证，权限认证，动态路由，压力测试，负载分配 等等
 */
@Component
public class PreFilter extends ZuulFilter {
    @Autowired
    private ZuulProperties zuulProperties;

    /**
     * 过滤器类型
     * @return
     */
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /**
     * 执行顺序，值越小，越优先
     * @return
     */
    public int filterOrder() {
        return 0;
    }

    /**
     * 过滤器是否生效
     * @return
     */
    public boolean shouldFilter() {
        Set<String> ignoredPatterns = zuulProperties.getIgnoredPatterns();
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String uri = request.getRequestURI();
        return !isIgnored(uri, ignoredPatterns);
    }

    /**
     * 启用过滤器，执行过滤逻辑
     * @return
     * @throws ZuulException
     */
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String token = request.getHeader("Authorization");
        if (StringUtils.isEmpty(token)){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(401);
            requestContext.setResponseBody("access without permission, please login!");
        }
        return null;
    }

    public boolean isIgnored(String uri, Set<String> ignoredPatterns) {
        for (String pattern : ignoredPatterns) {
            return uri.contains(pattern);
        }
        return false;
    }
}
